/*
 *
 *  Created by John David Duncan on 4/27/09.
 *  Copyright 2009 Sun Microsystems. All rights reserved.
 *
 */

/*
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; version 2 of the License.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

#include <vector>
extern "C" {
#include "innodb.h"
}

/* A preprocessor trick: */
/* ddltool error codes begin at 5000 (a higher value than any innodb error) */
#define TOOLERR(a,b) a,
enum {
   e_BASE_VALUE = 5000,
#include "errors.map"
   e_MAX
};
#undef TOOLERR

void init_constants(); 
void report(char **, const char *, const char *, ... );

enum {  
  /* various constants used in the parse tree.  For each value here 
   there should be a string defined in init_constants().  */
  
  /* object types */
  obj_Table = 1, obj_Database, obj_Column, obj_Index, obj_Var,
  
  /* column types */
  col_VARCHAR, col_CHAR, col_BLOB, col_INT, col_FLOAT, col_DOUBLE,
  
  /* index types */
  idx_index, idx_unique, idx_primary, 
  
  /* operations */ 
  op_create, op_alter, op_add, op_drop, op_truncate,
  op_describe, op_help, op_show, op_start, op_stop, op_set,
  
  /* The final entry */
  sql_const_max
};

/*
   SQLnode 
     --> SQLshow    SHOW tables, SHOW databases, SHOW variable
     --> SQLtable   CREATE / ALTER / DROP / TRUNCATE / DESCRIBE table
     --> SQLattr    column, index
*/

//     ------- SQLnode ------
/*  SQLnode is the base class used to build the SQL parse tree
    (though some statements are parsed into specific derived classes, below).
*/ 

class SQLnode {
 public: 
  int op;        // usually an operation (CREATE, ALTER, etc.)
  int type;      // usually an object type or a column type
  struct SQLflags {
    unsigned nullable   : 1 ;
    unsigned a_unsigned : 1 ;
    unsigned primary    : 1 ;
    unsigned is_column  : 1 ;
    unsigned is_index   : 1 ;
    unsigned is_scaled  : 1 ;
    unsigned redundant  : 1 ; 
    unsigned dynamic    : 1 ;
    unsigned compressed : 1 ;
  } flags;
  
  size_t size;
  
  char *sch;	// name of schema or database
  char *obj;	// name of table or object
  char *atr;	// name of column or attribute
  
  // SQLnode *child1;
  // SQLnode *child2;  
  std::vector <SQLnode *> list;

  char *value;

  SQLnode(int o = 0, int t = 0) : 
    op(o), type(t), flags(), 
    size(0), sch(0), obj(0), atr(0), 
    list(), value(0)  { 
  };
  virtual ~SQLnode() {};
  
  virtual char * name()  { return type == obj_Database ? sch : obj; };
  virtual int  Run();
  virtual void Dump(char **p, const char *s);
};

//     ------- SQLshow ------
/*  SQLshow represents SHOW TABLES, SHOW DATABASES, SHOW <variable>
 */
class SQLshow : public SQLnode {
private:
  int show_tables();
public: 
  int Run();
  
  SQLshow() : SQLnode(op_show) {};
};


//     ------- SQLtable ------
/*  SQLtable represents CREATE TABLE, ALTER TABLE, DROP TABLE, 
    TRUNCATE TABLE, and DESCRIBE.
*/
class SQLtable : public SQLnode {
 private:
  int create(const char *);
 public: 
  SQLtable(int o) : SQLnode(o, obj_Table) {} ;
  void push_attr(SQLnode *a)   { list.push_back(a); };
  int  Run();
  void Dump(char **, const char *);
};


//     ------- SQLattr ------
/*  Represents a column or an index.
 */
class SQLattr : public SQLnode {
 public:
  SQLattr(int o = 0) : SQLnode(o) {};
  SQLattr(char *n, int sz) : SQLnode() { atr = n; is_column(); size = sz; };

  void is_index()   { flags.is_index = 1; type = idx_index; };
  void is_column()  { flags.is_column = 1; size = 0; flags.nullable = 1; };
  void unique()     { type = idx_unique;  };
  void pk()         { flags.primary = 1;  if(flags.is_index) type = idx_primary;  };
  void not_null()   { flags.nullable = 0; };
  void add_idx_col(char *n, int sz) { list.push_back(new SQLattr(n,sz)); };

  char * name() { return atr; }
  int  Run();
  void Dump(char **, const char *);
  int create_col(ib_tbl_sch_t);
  int create_idx(ib_tbl_sch_t);
};


//     ------ QualifiedName ------
//     creates a const char * name,
//     "schema.object" or "schema/object"
class QualifiedName {
 private:
  char *_name;
 public:
  QualifiedName(char *, char *, char div ='.');
  const char *name() { return (const char *) _name; };
  ~QualifiedName() { delete _name; };
};

 

